

import decimal
import logging
import requests
import json
from datetime import datetime
# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 基础信息
app_id = 'XXX'
app_secret = 'XXX'
# 多维表格信息
# https://https://isw1t6yp68.feishu.cn/base/111?table=222&view=333
app_token = '111'
source_table_id = '222'
source_view_id = '333'
# 电子表格信息
# https://https://isw1t6yp68.feishu.cn/sheets/444?sheet=555
spreadsheet_token = '444'
sheet_id = '555'
def get_access_token(app_id, app_secret):
    """
    获取tenant_access_token
    :param app_id: 
    :param app_secret: 
    :return: 
    """
    url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
    payload = {
        "app_id": app_id,
        "app_secret": app_secret
    }
    response = requests.post(url, json=payload)
    data = response.json()
    if 'tenant_access_token' in data:
        return data['tenant_access_token']
    else:
        print("Failed to get access token:", data)
        return None

# TODO 1、分页读取多维数据
def read_table_page_size(tenant_access_token, app_token, table_id, page_token='', page_size=20):
    # 多了分页参数
    url = f"https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/search?page_size={page_size}&page_token={page_token}&user_id_type=user_id"
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {tenant_access_token}'
    }
    body = {
        "view_id": source_view_id,
        "field_names": [
            "日期",
            "时间",
            "手机号",
            "微信昵称",
            "年级",
            "渠道",
            "跟进人",
            "用户状态",
            "学情沟通/挖需情况",
            "是否加v",
            "是否拉群",
            "约课时间",
            "挖需情况",
            "教材版本",
            "学习进度",
            "渠道备注",
            "地区（省/市）",
            "学习目标",
            "外呼次数",
            "出报告人",
            "负责人",
            "意向度",
            "成交额",
            "跟进时效性",
            "社群跟进人",
            "是否重复"
        ],
        "automatic_fields": False
    }
    response = requests.post(url, headers=headers, json=body)
    return response.json()

def write_data_to_sheet(access_token, spreadsheet_token, sheet_id, data):
    """
    写入电子表格
    :param access_token:
    :param spreadsheet_token:
    :param sheet_id:
    :param data:
    :return:
    """
    url = f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values'
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Content-Type': 'application/json; charset=utf-8'
    }
    payload = {
        'valueRange': {
            'range': f'{sheet_id}!A1:AH',
            'values': data
        }
    }
    response = requests.put(url, headers=headers, json=payload)
    if response.status_code == 200 and response.json().get('code') == 0:
        logging.info('数据写入成功')
    else:
        logging.error('数据写入失败: %s', response.text)

# TODO 2、新增覆盖批次写入
def write_data_to_sheet_in_batches(access_token, spreadsheet_token, sheet_id, data, batch_size=400):
    """
    分批写入电子表格
    :param access_token:
    :param spreadsheet_token:
    :param sheet_id:
    :param data:
    :param batch_size: 每批写入的记录数
    :return:
    """
    url = f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values'
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Content-Type': 'application/json; charset=utf-8'
    }

    total_records = len(data)
    for start in range(0, total_records, batch_size):
        end = start + batch_size
        batch_data = data[start:end]

        payload = {
            'valueRange': {
                'range': f'{sheet_id}!A{start + 1}:AH',  # 动态计算写入的起始行
                'values': batch_data
            }
        }

        response = requests.put(url, headers=headers, json=payload)
        if response.status_code == 200 and response.json().get('code') == 0:
            logging.info(f'数据写入成功: {start + 1} 到 {end} 行')
        else:
            logging.error('数据写入失败: %s', response.text)
            break

# TODO 3、新增一个追加写入
def append_data_to_sheet(access_token, spreadsheet_token, sheet_id, data):
    """
    追加写入电子表格
    :param access_token:
    :param spreadsheet_token:
    :param sheet_id:
    :param data:
    :return:
    """
    url = f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/values_prepend'
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Content-Type': 'application/json; charset=utf-8'
    }
    payload = {
        'valueRange': {
            'range': f'{sheet_id}!A1:AH',
            'values': data
        }
    }
    response = requests.post(url, headers=headers, json=payload)
    if response.status_code == 200 and response.json().get('code') == 0:
        logging.info('数据写入成功')
    else:
        logging.error('数据写入失败: %s', response.text)
def main():
    # 获取token
    access_token = get_access_token(app_id, app_secret)

    # “page_token” 是一个翻页参数，首页没有该参数，从首页响应体中获取
    page_token = ''
    # api单次读取为500
    page_size = 500
    # 用于判断有没有更多的页，有则返回 True。
    has_more = True
    records_to_write = []
    while has_more:
        result = read_table_page_size(access_token, app_token, source_table_id, page_token, page_size)

        if result['code'] == 0:
            page_token = result['data'].get('page_token')
            has_more = result['data'].get('has_more')
            print(result['data'].get('items'))

        items = result['data']['items']
        # records_to_write = []
        records_to_write.append(["name", "age"])

        for item in items:
            fields = item.get('fields')
            # 日期
            timestamp = fields.get('日期')
            if timestamp is not None:
                try:
                    date = datetime.fromtimestamp(timestamp / 1000).strftime('%Y/%m/%d')
                except ValueError:
                    date = 'Invalid Timestamp'
            else:
                date = None
            # 时间
            timestamp = fields.get('时间')
            if timestamp is not None:
                try:
                    time = datetime.fromtimestamp(timestamp / 1000).strftime('%Y/%m/%d %I:%M:%S')
                except ValueError:
                    time = 'Invalid Timestamp'
            else:
                time = None
            # 手机号
            phone = fields.get('手机号')
            # 微信昵称
            wechatName = fields.get('微信昵称', '')
            # 年级
            grade = fields.get('年级')
            # 渠道
            resouce = fields.get('渠道')
            # 跟进人
            follower = fields.get('跟进人')
            # 用户状态
            userStatus = fields.get('用户状态')
            # 学情沟通/挖需情况
            studyStatus = fields.get('学情沟通/挖需情况')
            # 是否加v
            isAddv = fields.get('是否加v', False)
            isAddv_int = 1 if isAddv else 0
            # 是否拉群
            isGroup = fields.get('是否拉群', False)
            isGroup_int = 1 if isAddv else 0
            # 约课时间
            timestamp = fields.get('约课时间')
            if timestamp is not None:
                try:
                    arrangeTime = datetime.fromtimestamp(timestamp / 1000).strftime('%Y/%m/%d %I:%M:%S')
                except ValueError:
                    arrangeTime = 'Invalid Timestamp'
            else:
                arrangeTime = None
            # 挖需情况
            diagNeed = fields.get('挖需情况')
            # 教材版本
            version = fields.get('教材版本')
            # 学习进度
            process = fields.get('学习进度')
            # 试听课安排
            sourceText = fields.get('渠道备注')
            # 地区（省/市）
            area = fields.get('地区（省/市）')
            # 学习目标
            goal = fields.get('学习目标')
            # 外呼次数
            callTimes = fields.get('外呼次数', 0)
            try:
                callTimes = int(callTimes)
            except (ValueError, TypeError):
                callTimes = 0
            # 出报告人
            reporter = fields.get('出报告人')
            # 负责人
            mainer = fields.get('负责人')
            # 意向度
            scale = fields.get('意向度')
            # 成交额
            amount = fields.get('成交额')
            # 跟进时效性
            timely = fields.get('跟进时效性')
            # 社区跟进人
            socialFollower = fields.get('社群跟进人')
            # 是否重复
            again = fields.get('是否重复')

            records_to_write.append([date, time, phone, wechatName, grade, resouce, follower, userStatus, studyStatus, isAddv_int, isGroup_int, arrangeTime, diagNeed, version, process, sourceText, area, goal, callTimes, reporter, mainer, scale, amount, timely, socialFollower, again])
        # TODO 4 、如果要追加就打开这个方法
    append_data_to_sheet(access_token, spreadsheet_token, sheet_id, records_to_write)
    # print(f"打印结果{records_to_write}")
    # TODO 5、如果要覆盖就使用这个方法
    # write_data_to_sheet_in_batches (access_token, spreadsheet_token, sheet_id, records_to_write)
if __name__ == '__main__':
    main()